<template>
  <div class="app-container">

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleSelect"
          v-hasPermi="['xs:invoiceLine:add']"
          v-if="optType !== 'view'"
        >选择单据</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>



    <el-table
      v-loading="loading"
      :data="invoiceLineList"
      show-summary
      border
      :summary-method="getSummaries"
      @cell-mouse-enter="handleCellEnter()"
      @cell-mouse-leave="handleCellLeave()"
    >
      <el-table-column label="产品物料编码" width="140" align="center" prop="itemCode" />
      <el-table-column label="产品物料名称" width="160" align="center" prop="itemName" />
      <el-table-column label="单位" align="center" prop="unitOfMeasure" />
      <el-table-column label="项目名称" align="center" prop="projectName" />
      <el-table-column label="开票数量" align="center" prop="invoicedQuantity">
        <div class="invoicedQuantityItem" slot-scope="scope">
          <el-input
            class="item_input"
            v-model="scope.row.invoicedQuantity"
            size="mini"
            style="width: 100%;"
            :title="scope.row.invoicedQuantity"
            @blur="handleInvoicedQuantityBlur(scope.row)"
            v-if="optType !== 'view'"
          />
          <el-input
            class="item_input"
            v-model="scope.row.invoicedQuantity"
            size="mini"
            style="width: 100%;"
            :title="scope.row.invoicedQuantity"
            readonly
            v-if="optType === 'view'"
          />
        </div>
      </el-table-column>
      <el-table-column label="不含税单价" align="center" prop="noTaxPrice" />
      <el-table-column label="不含税金额" align="center" prop="noTaxTotal" />
      <el-table-column label="含税单价" align="center" prop="unitPrice">
        <div class="unitPriceItem" slot-scope="scope">
          <el-input
            class="item_input"
            v-model="scope.row.unitPrice"
            size="mini"
            style="width: 100%;"
            :title="scope.row.unitPrice"
            @blur="handleUnitPriceBlur(scope.row)"
            v-if="optType !== 'view'"
          />
          <el-input
            class="item_input"
            v-model="scope.row.unitPrice"
            size="mini"
            style="width: 100%;"
            :title="scope.row.unitPrice"
            readonly
            v-if="optType === 'view'"
          />
        </div>
      </el-table-column>
      <el-table-column label="含税金额" align="center" prop="price">
        <div class="priceItem" slot-scope="scope">
          <el-input
            class="item_input"
            v-model="scope.row.price"
            size="mini"
            style="width: 100%;"
            :title="scope.row.price"
            @blur="handlePriceBlur(scope.row)"
            v-if="optType !== 'view'"
          />
          <el-input
            class="item_input"
            v-model="scope.row.price"
            size="mini"
            style="width: 100%;"
            :title="scope.row.price"
            readonly
            v-if="optType === 'view'"
          />
        </div>
      </el-table-column>
      <el-table-column label="税率（%）" align="center" prop="taxRate">
        <template slot-scope="scope">
          <el-select
              v-model="scope.row.taxRate"
              placeholder="请选择税率"
              style="width:100%"
              @focus="(event) => onTaxRateFocus(scope.row)"
              @change="(value) => handleSelectChange(value, scope.row, scope.row.taxRate)">
            <el-option
                v-for="item in taxRateList"
                :key="item.taxRate"
                :label="item.taxRate"
                :value="item.taxRate"
                :disabled="optType === 'view'"
            >
            </el-option>
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="税额" align="center" prop="taxTotal" />
      <el-table-column label="关联单号" width="140" align="center" prop="sourceCode" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" v-if="optType !== 'view'">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['xs:invoiceLine:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <el-dialog title="选择单据" :visible.sync="openSelect" width="1400px" append-to-body>
      <el-card style="border-radius: 10px">
        <el-form :model="selectQuery" ref="selectQueryForm" size="small" :inline="true" v-show="true"
                 label-width="120px">
          <el-form-item label="出库单号" prop="salseCode">
            <el-input
                v-model="selectQuery.salseCode"
                placeholder="请输入出库单号"
                clearable
                @keyup.enter.native="handleSelectList"
            />
          </el-form-item>
          <el-form-item label="产品名称" prop="itemName">
            <el-input
                v-model="selectQuery.itemName"
                placeholder="请输入产品名称"
                clearable
                @keyup.enter.native="handleSelectList"
            />
          </el-form-item>
          <el-form-item label="项目名称" prop="projectName">
            <el-input
              v-model="selectQuery.projectName"
              placeholder="请输入项目名称"
              clearable
              @keyup.enter.native="handleSelectList"
            />
          </el-form-item>
          <el-form-item label="开始日期" prop="beginTime">
            <el-date-picker
                v-model="selectQuery.beginTime"
                type="date"
                placeholder="选择日期">
            </el-date-picker>
          </el-form-item>
          <el-form-item label="结束日期" prop="endTime">
            <el-date-picker
                v-model="selectQuery.endTime"
                type="date"
                placeholder="选择日期">
            </el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleSelectQuery">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetSelectQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </el-card>
      <div style="height: 15px"></div>
      <el-card style="border-radius: 10px">
        <el-table :data="selectList" ref="selectTable" @selection-change="handleSelectionChange" height="500">
          <el-table-column type="selection" width="40" align="center"/>
          <el-table-column label="出库单号" align="center" prop="salseCode"/>
          <el-table-column label="客户" align="center" prop="clientName"/>
          <el-table-column label="单据日期" align="center" prop="salseDate">
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.salseDate, '{y}-{m}-{d}') }}</span>
            </template>
          </el-table-column>
          <el-table-column label="出库单状态" align="center" prop="status">
            <template slot-scope="scope">
              <dict-tag :options="dict.type.order_type_status" :value="scope.row.status"/>
            </template>
          </el-table-column>
          <el-table-column label="项目名称" align="center" prop="projectName" />
          <el-table-column label="产品编号" align="center" prop="itemCode"/>
          <el-table-column label="产品名称" align="center" prop="itemName"/>
          <el-table-column label="单位" align="center" prop="unitOfMeasure"/>
          <el-table-column label="出库数量" align="center" prop="quantitySalse"/>
          <el-table-column label="未开票数量" align="center" prop="unInvoicedQuantity"/>
          <el-table-column label="已开票数量" align="center" prop="alreadyQuantity"/>
          <el-table-column label="含税单价" align="center" prop="unitPrice"/>
        </el-table>
        <pagination
            v-show="selectTotal>0"
            :total="selectTotal"
            :page.sync="selectQuery.pageNum"
            :limit.sync="selectQuery.pageSize"
            @pagination="handleSelectList"
        />
      </el-card>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleSaveInvoiceLine">确 定</el-button>
        <el-button @click="selectCancel">取 消</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import {
  listInvoiceLine,
  getInvoiceLine,
  delInvoiceLine,
  addInvoiceLine,
  updateInvoiceLine
} from "@/api/mes/xs/invoiceLine";
import { getSelectList } from "@/api/mes/wm/productsalse";
import { getTaxRateSelectData } from "@/api/mes/md/taxRate";

export default {
  name: "InvoiceLine",
  dicts: ['order_type_status'],
  props: {
    invoiceId: {
      type: Number,
      default: null
    },
    clientId: {
      type: Number,
      default: null
    },
    optType: {
      type: String,
      default: null
    }

  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 销售发票明细表格数据
      invoiceLineList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        invoiceId: this.invoiceId,
        itemId: null,
        itemCode: null,
        itemName: null,
        unitOfMeasure: null,
        invoicedQuantity: null,
        unitPrice: null,
        price: null,
        taxRate: null,
        sourceCode: null,
        lineStatus: null,
        attr1: null,
        attr2: null,
        attr3: null,
        attr4: null,
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
      },
      openSelect: false,
      selectQuery: {
        pageNum: 1,
        pageSize: 10,
        clientId: this.clientId,
        salseCode: null,
        itemName: null,
        beginTime: null,
        endTime: null,
        projectName: null,
      },
      selectList: [],
      selectTotal: 0,
      selectedRows: [],
      taxRateList:[],
      taxRateDefault: null,
      originalTaxRate: null,
      // 可修改单元格属性
      editProp: ['invoicedQuantity', 'unitPrice', 'price' ],
    };
  },
  created() {
    this.getList();
    this.getTaxRateSelectData();
  },
  watch: {
    invoiceId: function (newVal, oldVal) {
      if (newVal !== oldVal && newVal !== null) {
        this.queryParams.invoiceId = newVal;
        this.getList();
      }
    }
  },
  methods: {
    /** 查询销售发票明细列表 */
    getList() {
      this.loading = true;
      listInvoiceLine(this.queryParams).then(response => {
        this.invoiceLineList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        lineId: null,
        invoiceId: this.invoiceId,
        itemId: null,
        itemCode: null,
        itemName: null,
        unitOfMeasure: null,
        invoicedQuantity: null,
        noTaxPrice: null,
        noTaxTotal: null,
        unitPrice: null,
        price: null,
        taxRate: null,
        taxTotal: null,
        sourceCode: null,
        salseLineId: null,
        lineStatus: "未确认",
        remark: null,
        attr1: null,
        attr2: null,
        attr3: null,
        attr4: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
        projectId: null,
        projectCode: null,
        projectName: null,
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      const lineId = row.lineId || this.ids
      getInvoiceLine(lineId).then(response => {
        this.form = response.data;
        this.open = true;
        this.title = "修改销售发票明细";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.lineId != null) {
            updateInvoiceLine(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addInvoiceLine(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const lineIds = row.lineId || this.ids;
      this.$modal.confirm('是否确认删除销售发票明细编号为"' + lineIds + '"的数据项？').then(function() {
        return delInvoiceLine(lineIds);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('xs/invoiceLine/export', {
        ...this.queryParams
      }, `invoiceLine_${new Date().getTime()}.xlsx`)
    },
    // 打开选择框
    handleSelect() {
      this.openSelect = true;
      this.handleSelectList();
    },
    // 条件查询选择框列表
    handleSelectList() {
      getSelectList(this.selectQuery).then(response => {
        this.selectList = response.rows;
        this.selectTotal = response.total;
      })
    },
    // 搜索按钮操作
    handleSelectQuery() {
      this.selectQuery.pageNum = 1;
      this.handleSelectList();
    },
    // 重置按钮操作
    resetSelectQuery() {
      this.resetForm("selectQueryForm");
      this.handleQuery();
    },
    // 多选
    handleSelectionChange(val) {
      this.selectedRows = val;
    },
    // 选择取消
    selectCancel() {
      this.openSelect = false;
    },
    // 多选确定
    async handleSaveInvoiceLine() {
      const successList = [];
      const failList = [];
      for (const item of this.selectedRows) {
        this.form.invoiceId = this.invoiceId;
        this.form.itemId = item.itemId;
        this.form.itemCode = item.itemCode;
        this.form.itemName = item.itemName;
        this.form.unitOfMeasure = item.unitOfMeasure;
        this.form.projectId = item.projectId;
        this.form.projectCode = item.projectCode;
        this.form.projectName = item.projectName;
        this.form.invoicedQuantity = item.quantitySalse;
        this.form.noTaxPrice = parseFloat((
          ((item.quantitySalse * item.unitPrice) - (item.quantitySalse * item.unitPrice * this.taxRateDefault / 100))
          / item.quantitySalse).toFixed(2))
        this.form.noTaxTotal = parseFloat((
            (item.quantitySalse * item.unitPrice) - (item.quantitySalse * item.unitPrice * this.taxRateDefault / 100)
        ).toFixed(2))
        this.form.unitPrice = item.unitPrice;
        this.form.price = parseFloat((item.quantitySalse * item.unitPrice ).toFixed(2));
        this.form.taxRate = this.taxRateDefault;
        this.form.taxTotal = parseFloat((item.quantitySalse * item.unitPrice * this.taxRateDefault / 100).toFixed(2));
        this.form.sourceCode = item.salseCode;
        this.form.salseLineId = item.lineId;
        this.form.lineStatus = "未确认";
        this.form.attr3 = item.unInvoicedQuantity;
        try {
          await addInvoiceLine(this.form)
          successList.push(item)
        } catch (error) {
          failList.push(item);
          console.error('新增发票明细失败',error)
        }
      }
      if (successList.length > 0) {
        this.$modal.msgSuccess(`新增成功 ${successList.length} 条`);
      }

      if (failList.length > 0) {
        this.$modal.msgError(`新增失败 ${failList.length} 条，请查看控制台日志`);
      }
      this.openSelect = false;
      this.getList();
    },
    // 获取税率下拉框数据
    getTaxRateSelectData() {
      const query={
        isOpen: 0,
        taxType: '销项税'
      }
      getTaxRateSelectData(query).then(response => {
        this.taxRateList = response.data;
        this.taxRateList.forEach(item => {
          if(item.isDefault === 0){
            this.taxRateDefault = item.taxRate;
          }
        })
      })
    },
    // 获取原数据
    onTaxRateFocus(row) {
      this.originalTaxRate = row.taxRate;
    },
    // 改变税率
    async handleSelectChange(value, row) {
      const oldValue = this.originalTaxRate;
      if (!row.lineId) {
        this.$modal.msgWarning("请先保存该条数据后再修改税率");
        return;
      }
      // 如果值未发生变化，不进行请求
      if (value === oldValue) return;
      try {
        // 改变后税率
        row.taxRate = value;
        // 改变后税额
        row.taxTotal = parseFloat((row.invoicedQuantity * row.unitPrice * value / 100).toFixed(2));
        // 改变后不含税金额
        row.noTaxTotal = parseFloat((
          (row.invoicedQuantity * row.unitPrice) - (row.invoicedQuantity * row.unitPrice * value / 100)
        ).toFixed(2))
        // 改变后不含税单价
        row.noTaxPrice = parseFloat((
          ((row.invoicedQuantity * row.unitPrice) - (row.invoicedQuantity * row.unitPrice * value / 100))
          / row.invoicedQuantity).toFixed(2))
        await updateInvoiceLine(row);
        this.getList();
        this.$emit('update');
        this.$modal.msgSuccess("税率更新成功");
      } catch (error) {
        this.$modal.msgError("税率更新失败");
        console.error('税率更新失败:', error);
        // 回滚 UI 上的值
        row.taxRate = value;
      } finally {
        this.originalTaxRate = null;
      }
    },
    // 合计
    getSummaries(param) {
      const {columns, data} = param;
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计';
          return;
        }
        const values = data.map(item => Number(item[column.property]));
        if (column.property === 'price') {
          if (!values.every(value => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr);
              if (!isNaN(value)) {
                return prev +curr;
              }else {
                return prev;
              }
            }, 0);
            sums[index] += ' 元';
          }else {
            sums[index] = '---';
          }
        }else {
          sums[index] = '';
        }
      });
      return sums;
    },
    // 获取当前list
    getInvoiceLineList() {
      return this.invoiceLineList;
    },
    // 列表单元格鼠标进入事件
    handleCellEnter (row, column, cell, event) {
      if (column) {
        const property = column.property
        if (this.editProp.includes(property)) {
          cell.querySelector('.item_input').style.display = 'block'
        }
      }
    },
    // 列表单元格鼠标离开事件
    handleCellLeave (row, column, cell, event) {
      if (column) {
        const property = column.property
        if (this.editProp.includes(property)) {
          cell.querySelector('.item_input').style.display = 'none'
        }
      }
    },
    // 开票数量输入框失去焦点事件
    handleInvoicedQuantityBlur(row) {
      const invoicedQuantity = parseFloat(row.invoicedQuantity)
      if (isNaN(invoicedQuantity) ||
        !Number.isInteger(invoicedQuantity) ||
        invoicedQuantity <= 0 ||
        invoicedQuantity > row.attr3) {
        this.$modal.msgError("请输入大于0，小于等于" + row.attr3 + "的正整数");
        this.getList();
        return;
      }
      // 改变含税金额
      row.price = parseFloat((invoicedQuantity * row.unitPrice).toFixed(2));
      // 改变税额
      row.taxTotal = parseFloat((invoicedQuantity * row.unitPrice * row.taxRate / 100).toFixed(2));
      // 改变不含税金额
      row.noTaxTotal = parseFloat((
        (invoicedQuantity * row.unitPrice) - (invoicedQuantity * row.unitPrice * row.taxRate / 100)
      ).toFixed(2));
      // 改变不含税单价
      row.noTaxPrice = parseFloat((
        ((invoicedQuantity * row.unitPrice) - (invoicedQuantity * row.unitPrice * row.taxRate / 100))
        / invoicedQuantity).toFixed(2));
      updateInvoiceLine(row).then(response => {
        this.$modal.msgSuccess("修改成功");
        this.getList();
        this.$emit('update');
      });
    },
    // 单价输入框失去焦点事件
    handleUnitPriceBlur(row) {
      const unitPrice = parseFloat(row.unitPrice)
      if (isNaN(unitPrice) || unitPrice <= 0) {
        this.$modal.msgError("单价必须为数字，且不能包含特殊字符或文字");
        this.getList();
        return;
      }
      // 改变含税金额
      row.price = parseFloat((row.invoicedQuantity * unitPrice).toFixed(2));
      // 改变税额
      row.taxTotal = parseFloat((row.invoicedQuantity * unitPrice * row.taxRate / 100).toFixed(2));
      // 改变不含税金额
      row.noTaxTotal = parseFloat((
        (row.invoicedQuantity * unitPrice) - (row.invoicedQuantity * unitPrice * row.taxRate / 100)
      ).toFixed(2))
      // 改变不含税单价
      row.noTaxPrice = parseFloat((
        ((row.invoicedQuantity * unitPrice) - (row.invoicedQuantity * unitPrice * row.taxRate / 100))
        / row.invoicedQuantity).toFixed(2))

      updateInvoiceLine(row).then(response => {
        this.$modal.msgSuccess("修改成功");
        this.getList();
        this.$emit('update');
      });
    },
    // 金额输入框失去焦点事件
    handlePriceBlur(row) {
      const price = parseFloat(row.price)
      if (isNaN(price) || price <= 0) {
        this.$modal.msgError("金额必须为数字，且不能包含特殊字符或文字");
        this.getList();
        return;
      }
      // 改变单价
      row.unitPrice = parseFloat((price / row.invoicedQuantity).toFixed(2));
      // 改变税额
      row.taxTotal = parseFloat((row.invoicedQuantity * row.unitPrice * row.taxRate / 100).toFixed(2));
      // 改变不含税金额
      row.noTaxTotal = parseFloat((
        (row.invoicedQuantity * row.unitPrice) - (row.invoicedQuantity * row.unitPrice * row.taxRate / 100)
      ).toFixed(2));
      // 改变不含税单价
      row.noTaxPrice = parseFloat((
        ((row.invoicedQuantity * row.unitPrice) - (row.invoicedQuantity * row.unitPrice * row.taxRate / 100))
        / row.invoicedQuantity).toFixed(2));
      updateInvoiceLine(row).then(response => {
        this.$modal.msgSuccess("修改成功");
        this.getList();
        this.$emit('update');
      });
    }

  }
};
</script>
